package com.yanqu.road.server.manager.systemgroup;

import com.yanqu.road.dao.impl.systemgroup.ServerWeekDataDaoImpl;
import com.yanqu.road.dao.impl.systemgroup.SystemServerGroupWeekDataDaoImpl;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.servercenter.ChannelSystemConfig;
import com.yanqu.road.entity.servercenter.CrossServerInfo;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.systemgroup.OpenDayServerGroup;
import com.yanqu.road.entity.systemgroup.common.ServerWeekData;
import com.yanqu.road.entity.systemgroup.common.SystemServerGroupWeekData;
import com.yanqu.road.entity.systemgroup.newmonopolymarket.config.NewMonopolyMarketSystemConfigInfo;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.MathHelper;
import com.yanqu.road.logic.pb.ServerSystemGroupPb;
import com.yanqu.road.pb.union.SystemGroupMatchProto;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.connect.CrossAgentLinkedControl;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.config.CrossSystemLoopMgr;
import com.yanqu.road.server.manager.union.activitygroup.UnionActivityGroupLockMgr;
import com.yanqu.road.server.manger.ChannelSystemConfigMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.config.Config;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class Cross3SystemWeekGroupMatchMgr extends TempCrossMgr {

    private static Logger logger = LogManager.getLogger(Cross3SystemWeekGroupMatchMgr.class.getName());

    //区服强度数据
    //weekId,systemId,serverId
    private static Map<Integer, Map<Integer, Map<Long, ServerWeekData>>>  serverAbilityMap;

    //weekId,systemId
    private static Map<Integer, Map<Integer, List<SystemServerGroupWeekData>>> systemMatchGroupMap;

    @Override
    public boolean removeExpireData() throws Exception {
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        int weekId = GameConfig.getSystemThisWeekId();
        serverAbilityMap = new ConcurrentHashMap<>();
        serverAbilityMap.put(weekId, new ServerWeekDataDaoImpl().getServerWeekData(weekId));
        systemMatchGroupMap = new ConcurrentHashMap<>();
        systemMatchGroupMap.put(weekId, new SystemServerGroupWeekDataDaoImpl().getSystemServerGroupWeekData(weekId));
        return true;
    }

    @Override
    public boolean save() {

        for (Map.Entry<Integer, Map<Integer, Map<Long, ServerWeekData>>> entry : serverAbilityMap.entrySet()) {
            for (Map.Entry<Integer, Map<Long, ServerWeekData>> mapEntry : entry.getValue().entrySet()) {
                for (Map.Entry<Long, ServerWeekData> dataEntry : mapEntry.getValue().entrySet()) {
                    ServerWeekData data = dataEntry.getValue();
                    if(data.isInsertOption()){
                        new ServerWeekDataDaoImpl().add(data);
                    }else if(data.isUpdateOption()) {
                        new ServerWeekDataDaoImpl().update(data);
                    }
                }
            }
        }

        for (Map.Entry<Integer, Map<Integer, List<SystemServerGroupWeekData>>> entry : systemMatchGroupMap.entrySet()) {
            for (Map.Entry<Integer, List<SystemServerGroupWeekData>> listEntry : entry.getValue().entrySet()) {
                List<SystemServerGroupWeekData> list = listEntry.getValue();
                for (int i = 0; i < list.size(); i++) {
                    SystemServerGroupWeekData data = list.get(i);
                    if(data.isInsertOption()){
                        new SystemServerGroupWeekDataDaoImpl().add(data);
                    }else if(data.isUpdateOption()) {
                        new SystemServerGroupWeekDataDaoImpl().update(data);
                    }
                }
            }
        }

        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }


    public static void checkUploadData(){

        for (int systemId : getSystemIdList()) {

            //准备期，周五0点至周六10点
            if(!inPreparationPeriod(systemId)){
                return;
            }

            //轮循到本系统的所有区服
            List<ServerInfo> serverInfoList = CrossSystemLoopMgr.getLoopServerList(systemId);
            if(serverInfoList.size() == 0){
                getLogger().info("checkUploadData 轮询没有取到区服数据");
                if(Config.isDebug()){
                    serverInfoList = ServerListMgr.getChannelServerList(666);
                }else {
                    return;
                }
            }

            int thisWeekId = GameConfig.getSystemThisWeekId();
            if(!serverAbilityMap.containsKey(thisWeekId)){
                serverAbilityMap.put(thisWeekId, new ConcurrentHashMap<>());
            }
            if(!serverAbilityMap.get(thisWeekId).containsKey(systemId)){
                serverAbilityMap.get(thisWeekId).put(systemId, new ConcurrentHashMap<>());
            }

            if(serverInfoList.size() == serverAbilityMap.get(thisWeekId).get(systemId).size()){
                return;
            }

            for (ServerInfo serverInfo : serverInfoList) {
                if(!serverAbilityMap.get(thisWeekId).get(systemId).containsKey(serverInfo.getServerId())){
                    SystemGroupMatchProto.Cross3NotifyServerUploadAbilityMsg.Builder builder = SystemGroupMatchProto.Cross3NotifyServerUploadAbilityMsg.newBuilder();
                    builder.setSystemId(systemId);
                    if(!Config.isDebug()) {
                        MessageHelper.sendPacket(serverInfo.getServerId(), 0, YanQuMessageUtils.buildMessage(Protocol.S_CROSS_SYSTEM_SERVER_UPLOAD_ABILITY, builder));
                    }
                }
            }
        }
    }

    public static void uploadServerAbility(int systemId, long serverId, BigInteger ability){
        int thisWeekId = GameConfig.getSystemThisWeekId();
        if(!serverAbilityMap.containsKey(thisWeekId)){
            return;
        }
        if(!serverAbilityMap.get(thisWeekId).containsKey(systemId)){
           return;
        }
        if(serverAbilityMap.get(thisWeekId).get(systemId).containsKey(serverId)){
            return;
        }
        ServerWeekData weekData = new ServerWeekData();
        weekData.setInsertOption();
        weekData.setWeekId(thisWeekId);
        weekData.setSystemId(systemId);
        weekData.setServerId(serverId);
        weekData.setAbility(ability);
        serverAbilityMap.get(thisWeekId).get(systemId).put(serverId, weekData);
    }

    public static void checkGrouping(){
        for (int systemId : getSystemIdList()) {
            checkGrouping(systemId);
        }
    }

    public static void checkGrouping(int systemId){

        //准备期，周五0点至周六10点
        if(!inPreparationPeriod(systemId)){
            return;
        }

        //轮循到本系统的所有区服
        List<ServerInfo> serverInfoList = CrossSystemLoopMgr.getLoopServerList(systemId);
        if(serverInfoList.size() == 0){
            logger.info("系统 {}， 轮询区服范围空", systemId);
            if(Config.isDebug()){
                serverInfoList = ServerListMgr.getChannelServerList(666);
            }else {
                return;
            }
        }

        int thisWeekId = GameConfig.getSystemThisWeekId();
        if(!serverAbilityMap.containsKey(thisWeekId)){
            return;
        }
        Map<Integer, Map<Long, ServerWeekData>>  systemServerWeekDataMap =  serverAbilityMap.get(thisWeekId);
        if(systemServerWeekDataMap == null){
            return;
        }
        Map<Long, ServerWeekData> serverWeekDataMap = serverAbilityMap.get(thisWeekId).get(systemId);
        if(serverWeekDataMap == null){
            return;
        }

        //区服强度大小 要包含 区服范围
        List<Long> idList = new ArrayList<>();
        for (ServerInfo serverInfo : serverInfoList) {
            idList.add(serverInfo.getServerId());
        }
        idList.removeAll(serverWeekDataMap.keySet());
        if(idList.size() > 0) {
            if(serverInfoList.size() > 0 && Config.isDebug() && serverWeekDataMap.size() == 0){
                Random random = new Random();
                //模拟强度
                for (ServerInfo serverInfo : serverInfoList) {
                    ServerWeekData serverWeekData = new ServerWeekData();
                    serverWeekData.setInsertOption();
                    serverWeekData.setWeekId(thisWeekId);
                    serverWeekData.setServerId(serverInfo.getServerId());
                    serverWeekData.setSystemId(systemId);
                    serverWeekData.setUpdateTime(DateHelper.getCurrentSecond());
                    serverWeekData.setAbility(BigInteger.valueOf(random.nextInt(1000000)));
                    serverWeekDataMap.put(serverInfo.getServerId(), serverWeekData);
                }
            }else {
                logger.info("系统 {}， 等待区服上报区服强度，{}", systemId, idList);
            }
            return;
        }

        if(systemMatchGroupMap.containsKey(thisWeekId)){
            if(systemMatchGroupMap.get(thisWeekId).containsKey(systemId)){
                //已有分组
                return;
            }
        }

        List<ServerWeekData> tempList = new ArrayList<>(serverWeekDataMap.values());
        tempList.sort((o1, o2) -> o2.getAbility().compareTo(o1.getAbility()));
        for (ServerWeekData serverWeekData : tempList) {
            getLogger().info("============{}-[{}]", serverWeekData.getServerId(), serverWeekData.getAbility().toString());
        }

        int channelId = ConfigHelper.getInt("channelId");
        Map<String, ChannelSystemConfig> systemConfigMap = ChannelSystemConfigMgr.getSystemConfigMap(channelId, eSystemId.NewMonopolyMarket.getValue());
        if(systemConfigMap == null){
            logger.info("系统 {} 缺失 t_s_system_config 配置" , eSystemId.NewMonopolyMarket.getValue());
            return;
        }
        ChannelSystemConfig channelSystemConfig = systemConfigMap.get(NewMonopolyMarketSystemConfigInfo.QUECHANG_BIGSEVERGROUP_RULE);
        if(channelSystemConfig == null){
            logger.info("系统 {} 缺失 t_s_system_config 配置 {}" , eSystemId.NewMonopolyMarket.getValue(), NewMonopolyMarketSystemConfigInfo.QUECHANG_BIGSEVERGROUP_RULE);
            return;
        }

        //按开服天数划分区间大组，不足的区间合并到相邻区间
        List<Integer> openDayRange = new ArrayList<>();
        //开服区间最终区服數量
        Map<Integer, Integer> bigGroupRangeMin = new HashMap<>();
        //大跨服最小区服數量
        Map<Integer, Integer> bigGroupMin = new HashMap<>();

        List<String> rangStringList = StringUtils.stringToStringList(channelSystemConfig.getValue(), "\\|");
        for (String str : rangStringList) {
            List<Integer> paramList = StringUtils.stringToIntegerList(str, "-");
            openDayRange.add(paramList.get(0));
            bigGroupRangeMin.put(paramList.get(0), paramList.get(1));
            bigGroupMin.put(paramList.get(0), paramList.get(2));
        }

        //区间大组划分
        List<OpenDayServerGroup> rangeGroupList = getBigGroup(serverInfoList, openDayRange);

        if(rangeGroupList.size() != openDayRange.size()){
            logger.info("系统 {}，分区大小{},实际分区大小{}", systemId, rangeGroupList.size(), openDayRange.size());
        }

        getLogger().info("======Match[{}] 按开服天数分组 start", thisWeekId);
        for (OpenDayServerGroup group : rangeGroupList) {
            getLogger().info("======Match[{}] 按开服天数分组 开服天数：{}， 区服：{}", thisWeekId, group.getOpenDay(), group.getServerIdList());
        }
        getLogger().info("======Match[{}] 按开服天数分组 end", thisWeekId);


        //合并分区
        rangeGroupList = mergeRangeGroup(bigGroupRangeMin, rangeGroupList);

        getLogger().info("======Match[{}] 按开服天数分组 合并后", thisWeekId);
        getLogger().info("======Match[{}] 按开服天数分组 start", thisWeekId);
        for (OpenDayServerGroup group : rangeGroupList) {
            getLogger().info("======Match[{}] 按开服天数分组 开服天数：{}， 区服：{}", thisWeekId, group.getOpenDay(), group.getServerIdList());
        }
        getLogger().info("======Match[{}] 按开服天数分组 end", thisWeekId);

        //每个分组区服数
        //int numPerGroup = 50;
        //分区划分成分组
        List<SystemServerGroupWeekData> allGroupList = sharingGroup(systemId, thisWeekId, bigGroupRangeMin, rangeGroupList, bigGroupMin, serverWeekDataMap);

        getLogger().info("======Match[{}] 按开服天数分组 最终分组", thisWeekId);
        getLogger().info("======Match[{}] 按开服天数分组 start", thisWeekId);
        for (SystemServerGroupWeekData group : allGroupList) {
            getLogger().info("======Match[{}] 按开服天数分组 开服天数：{}， 区服：{}", thisWeekId, group.getOpenDay(), group.getServerIdList());
        }
        getLogger().info("======Match[{}] 按开服天数分组 end", thisWeekId);


        List<Integer> selfCrossIdList = new ArrayList<>();
        String testCrossBattleServerId = ConfigHelper.getValue("testCrossBattleServerId");
        if (!StringUtils.isNullOrEmpty(testCrossBattleServerId)) {
            selfCrossIdList = StringUtils.stringToIntegerList(testCrossBattleServerId, ";");
        }

        //分配跨服id
        int startRandom = new Random().nextInt(100);
        List<CrossServerInfo> crossServerInfoList = UnionActivityGroupLockMgr.getActivityCrossList();
        for (SystemServerGroupWeekData groupWeekData : allGroupList) {
            if(selfCrossIdList.size() > 0){
                groupWeekData.setCrossServerIdNeedSync(selfCrossIdList.get(startRandom++ % selfCrossIdList.size()));
            }else {
                groupWeekData.setCrossServerIdNeedSync(crossServerInfoList.get(startRandom++ % crossServerInfoList.size()).getCrossServerId());
                if(Config.isDebug()){
                    groupWeekData.setCrossId(99900027);
                }
            }
            groupWeekData.setNoSyncServerSet(groupWeekData.getServerIdList());
        }

        if(!systemMatchGroupMap.containsKey(thisWeekId)){
            systemMatchGroupMap.put(thisWeekId, new ConcurrentHashMap<>());
        }
        systemMatchGroupMap.get(thisWeekId).put(systemId, allGroupList);

        syncMatchGroup(systemId);
    }

    /**
     * 分区划分成分组
     * @param systemId  系统
     * @param thisWeekId 周id
     * @param bigGroupRangeMin 每个分组区服数
     * @param rangeGroupList 开服天数分区
     * @return
     */
    public static List<SystemServerGroupWeekData> sharingGroup(int systemId, int thisWeekId, Map<Integer, Integer> bigGroupRangeMin,
                                                               List<OpenDayServerGroup> rangeGroupList, Map<Integer, Integer> bigGroupMin , Map<Long, ServerWeekData> serverWeekDataMap) {

        Date now = new Date();

        //每个区间，再按固定的服务器数量均分多个大跨服分组，区间内的区服按区服强度分配
        //所有区间，再按强度划分大跨服分组。（中小跨服由业务系统划分）
        int groupId = 0;
        List<SystemServerGroupWeekData> allList = new ArrayList<>();
        //每个分组区服数
        //int numPerGroup = 50;
        //每个分组最小区服数
        for (OpenDayServerGroup group : rangeGroupList) {
            int numPerGroup = bigGroupRangeMin.get(group.getOpenDay());
            int minNumPerGroup = bigGroupMin.get(group.getOpenDay());
            int totalNum = group.getNum();
            List<Integer> groupNumList = CrossSystemWeekGroupMatchHelper.divideGroupNum(numPerGroup, minNumPerGroup, totalNum);
            getLogger().info("====sharingGroup 开服天数:{}, 每组大小 {}， 最小數量 {}, 区服范围 {}", group.getOpenDay(), numPerGroup, minNumPerGroup, group.getServerIdList());
            getLogger().info("====sharingGroup 每组數量 {}", groupNumList);


            //方差最小的分组
            List<List<Long>> bestListList = null;
            BigDecimal bestValue = null;

            //所有区服
            List<Long> allServerList = new ArrayList<>(group.getServerIdList());

            //计算次数
            int tryTimes = 100;
            Random random = new Random();
            for (int i = 0; i < tryTimes; i++) {

                ArrayList<Long> randomServerList = new ArrayList<>(allServerList);
                Collections.shuffle(randomServerList);

                // 生成数据
                List<List<Long>> groupServerList = new ArrayList<>();
                for (int j = 0; j < groupNumList.size(); j++) {
                    groupServerList.add(new ArrayList<>());
                }

                // 随机填充各个分组
                for (int k = 0; k < groupNumList.size(); k++) {
                    int groupNum = groupNumList.get(k);
                    int add = 0;
                    while (add < groupNum && randomServerList.size() > 0){
                        int idx = random.nextInt(randomServerList.size());
                        groupServerList.get(k).add(randomServerList.remove(idx));
                        add++;
                    }
                }

                //计算方差
                // 拿赚速计算方差
                List<BigInteger> abilityList = new ArrayList<>();
                for (List<Long> unionList : groupServerList) {
                    BigInteger groupEarnSpeed = BigInteger.ZERO;
                    for (long sid : unionList) {
                        groupEarnSpeed = groupEarnSpeed.add(serverWeekDataMap.get(sid).getAbility());
                    }
                    abilityList.add(groupEarnSpeed);
                }
                BigDecimal variance = MathHelper.calcVariance(abilityList);
                // 比较最佳结果
                if (bestListList == null || variance.compareTo(bestValue) < 0) {
                    bestListList = groupServerList;
                    bestValue = variance;
                    getLogger().info("====sharingGroup 当前方差 {}", variance);
                    for (List<Long> list : bestListList) {
                        getLogger().info("====sharingGroup 当前各分组 {}", StringUtils.listToString(list, ","));
                    }
                }
            }

            for (List<Long> sIdList : bestListList) {
                SystemServerGroupWeekData groupWeekData = new SystemServerGroupWeekData();
                groupWeekData.setInsertOption();
                groupWeekData.setSystemId(systemId);
                groupWeekData.setGroupId(++groupId);
                groupWeekData.setOpenDay(group.getOpenDay());
                groupWeekData.setWeekId(thisWeekId);
                groupWeekData.setAddTime(now);
                groupWeekData.setNum(sIdList.size());

                //组内还是按能力排序
                sIdList.sort((o1, o2) -> {
                    ServerWeekData swd1 = serverWeekDataMap.get(o1);
                    ServerWeekData swd2 = serverWeekDataMap.get(o2);
                    return swd2.getAbility().compareTo(swd1.getAbility());
                });
                groupWeekData.getServerIdList().addAll(sIdList);

                allList.add(groupWeekData);
                getLogger().info("====sharingGroup 分组结果 {}", sIdList);
            }
        }

        return allList;
    }

    /**
     * 不足区服个数的分区往开服天数大的分区合并
     * @param bigGroupMin 区间大组，最小区服数
     * @param bigGroupList 区间大组  正序
     *
     */
    private static List<OpenDayServerGroup> mergeRangeGroup(Map<Integer, Integer> bigGroupMin, List<OpenDayServerGroup> bigGroupList) {
        List<OpenDayServerGroup> result = new ArrayList<>();
        for (int i = bigGroupList.size() - 1; i >= 0; i--) {
            OpenDayServerGroup group = bigGroupList.get(i);
            int minGroupRange = bigGroupMin.get(group.getOpenDay());
            if(i > 0) {
                if (group.getNum() < minGroupRange) {
                    OpenDayServerGroup preGroup = bigGroupList.get(i - 1);
                    preGroup.setNum(preGroup.getNum() + group.getNum());
                    preGroup.getServerIdList().addAll(group.getServerIdList());
                } else {
                    result.add(group);
                }
            }else {
                result.add(group);
            }
        }
        Collections.reverse(result);
        List<OpenDayServerGroup> tempList = result;
        result = new ArrayList<>();
        for (int i = 0; i < tempList.size(); i++) {
            OpenDayServerGroup group = tempList.get(i);
            int minGroupRange = bigGroupMin.get(group.getOpenDay());
            if(i < tempList.size() - 1) {
                if (group.getNum() < minGroupRange) {
                    OpenDayServerGroup preGroup = tempList.get(i + 1);
                    preGroup.setNum(preGroup.getNum() + group.getNum());
                    preGroup.setOpenDay(group.getOpenDay());
                    preGroup.getServerIdList().addAll(group.getServerIdList());
                } else {
                    result.add(group);
                }
            }else {
                result.add(group);
            }
        }
        return result;
    }

    /**
     * 将区服按天数区间分组
     * @param serverInfoList 所有区服
     * @param openDayRange  开服天数区间范围
     * @return
     */
    private static List<OpenDayServerGroup> getBigGroup(List<ServerInfo> serverInfoList, List<Integer> openDayRange ) {
        Map<Integer, OpenDayServerGroup> resultMap = new HashMap<>();
        openDayRange.sort(Comparator.reverseOrder());
        logger.info("===getBigGroup openDayRange : {}", openDayRange);
        for (ServerInfo serverInfo : serverInfoList) {
            int openDay = ServerListMgr.getServerOpenDay(serverInfo);
            for (int day : openDayRange) {
                if(openDay >= day){
                    if(!resultMap.containsKey(day)){
                        resultMap.put(day, new OpenDayServerGroup(day));
                    }
                    OpenDayServerGroup openDayServerGroup = resultMap.get(day);
                    openDayServerGroup.setNum(1+ openDayServerGroup.getNum());
                    openDayServerGroup.addServerId(serverInfo.getServerId());
                    logger.info("===getBigGroup server[{}] 开服天数 {}，划分到开服天数 {} 范围", serverInfo.getServerId(), openDay, day);
                    break;
                }
            }
        }
        ArrayList<OpenDayServerGroup> openDayServerGroupList = new ArrayList<>(resultMap.values());
        openDayServerGroupList.sort(Comparator.comparingInt(OpenDayServerGroup::getOpenDay));
        return openDayServerGroupList;
    }

    /**
     * 系统准备期间
     * @param systemId 系统id
     */
    public static boolean inPreparationPeriod(int systemId){
        Calendar calendar = Calendar.getInstance();
        if(Config.isDebug()){
            return true;
        }
        return calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY;
    }

    /**
     * 获取系统id列表
     */
    public static List<Integer> getSystemIdList(){
        List<Integer> result = new ArrayList<>();
        result.add(eSystemId.NewMonopolyMarket.getValue());
        return result;
    }


    //-----------
    public static void syncMatchGroup() {
        for (int systemId : getSystemIdList()) {
            syncMatchGroup(systemId);
        }
    }

        /**
         * 同步分组
         */
    public static void syncMatchGroup(int systemId) {

        int thisWeekId = GameConfig.getSystemThisWeekId();
        Map<Integer, List<SystemServerGroupWeekData>> systemGroupMap = systemMatchGroupMap.get(thisWeekId);
        if (systemGroupMap == null || systemGroupMap.size() == 0) {
            return;
        }

        List<SystemServerGroupWeekData> groupWeekDataList = systemGroupMap.get(systemId);

        Map<Integer, List<SystemServerGroupWeekData>> syncMap = new ConcurrentHashMap<>();
        for (SystemServerGroupWeekData matchGroup : groupWeekDataList) {
            List<SystemServerGroupWeekData> list = syncMap.getOrDefault(matchGroup.getCrossId(), new ArrayList<>());
            list.add(matchGroup);
            syncMap.put(matchGroup.getCrossId(), list);
        }
        for (Map.Entry<Integer, List<SystemServerGroupWeekData>> entry : syncMap.entrySet()) {
            int crossId = entry.getKey();
            // 分组信息
            List<SystemServerGroupWeekData> groupList = entry.getValue();
            // 通知活动服更新
            notifyMatchGroup(thisWeekId, systemId, crossId, groupList);
        }
    }


    public static void notifyMatchGroup(int weekId, int systemId, int crossId, List<SystemServerGroupWeekData> matchGroupList) {
        // 同步到活动服
        SystemGroupMatchProto.Cross3NotifyMatchGroupToActivityMsg.Builder builder = SystemGroupMatchProto.Cross3NotifyMatchGroupToActivityMsg.newBuilder();
        builder.setWeekId(weekId);
        builder.setSystemId(systemId);
        builder.setCrossId(crossId);
        for (SystemServerGroupWeekData matchGroup : matchGroupList) {
            SystemGroupMatchProto.ServerSystemMatchGroupTemp.Builder groupTemp = ServerSystemGroupPb.parseMatchGroupTemp(matchGroup);
            builder.addGroup(groupTemp);
        }
        // 同步活动跨服
        MessageHelper.sendUnionActivityGroupPacket(
                CrossAgentLinkedControl.randomConnectionSeverId(),
                0,
                CrossProtocol.C_CROSS_SYSTEM_MATCH_GROUP_SYNC,
                builder,
                0,
                crossId,
                0);

        // 同步游戏服
        for (SystemServerGroupWeekData matchGroup : matchGroupList) {
            SystemGroupMatchProto.Cross3NotifyMatchGroupToGameMsg.Builder gameBuilder = SystemGroupMatchProto.Cross3NotifyMatchGroupToGameMsg.newBuilder();
            SystemGroupMatchProto.ServerSystemMatchGroupTemp.Builder groupTemp = ServerSystemGroupPb.parseMatchGroupTemp(matchGroup);
            gameBuilder.setSystemId(systemId);
            gameBuilder.setWeekId(weekId);
            gameBuilder.setGroup(groupTemp);

            for (Long serverId : matchGroup.getServerIdList()) {
                MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(Protocol.S_CROSS_SYSTEM_MATCH_GROUP_SYNC, gameBuilder));
                //getLogger().info("notify MatchGroup timer sync to serverID {}.{}", serverId, systemId);
            }
        }
    }
}
